package com.lse_from.config.interceptor

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.http.converter.BufferedImageHttpMessageConverter
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.http.converter.StringHttpMessageConverter
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
import java.nio.charset.Charset
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter

/**
 * LSE 请求拦截器
 * WebMvcConfigurationSupport 试用时不能加  @EnableWebMvc
 *
 * @author 祁雪
 */
@Configuration
class InterceptorConfig : WebMvcConfigurationSupport() {

    @Value("\${web.upload-path}")
    var path: String? = null

    /**
     * 注入跨域拦截器
     *
     * @return
     */
    @Bean
    fun getCrossInterceptorConfig(): CrossInterceptorConfig {
        return CrossInterceptorConfig()
    }

    override fun addInterceptors(registry: InterceptorRegistry) {
        // 添加跨域拦截器
        registry.addInterceptor(getCrossInterceptorConfig()).addPathPatterns("/**")
    }

    @Bean
    fun responseBodyConverter(): HttpMessageConverter<String?>? {
        return StringHttpMessageConverter(Charset.forName("UTF-8"))
    }

    override fun configureMessageConverters(
        converters: MutableList<HttpMessageConverter<*>?>
    ) {
        super.configureMessageConverters(converters)
        converters.add(responseBodyConverter())
        converters.add(messageConverter())
        converters.add(bufferedImageHttpMessageConverter())
    }

    override fun configureContentNegotiation(
        configurer: ContentNegotiationConfigurer
    ) {
        configurer.favorPathExtension(false)
    }

    /**
     * 配置静态资源访问
     *
     * @param registry
     */
    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
        registry.addResourceHandler("/**")
            .addResourceLocations("classpath:/META-INF/resources/")
            .addResourceLocations("classpath:/resources/")
            .addResourceLocations("classpath:/static/")
            .addResourceLocations("classpath:/public/")
            .addResourceLocations("file:$path")
        super.addResourceHandlers(registry);
    }


    /**
     * 配置json返回转换器
     *
     * @return
     */
    @Bean
    fun messageConverter(): MappingJackson2HttpMessageConverter? {
        val converter = MappingJackson2HttpMessageConverter()
        converter.objectMapper = getObjectMapper()!!
        return converter
    }

    @Bean
    fun getObjectMapper(): ObjectMapper? {
        val mapper = ObjectMapper()
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)

        val timeModule = JavaTimeModule()
        timeModule.addSerializer(
            LocalDateTime::class.java,
            LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        )
        timeModule.addSerializer(
            LocalDate::class.java,
            LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        )
        timeModule.addSerializer(
            LocalTime::class.java,
            LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))
        )

        mapper.registerModule(timeModule)

        return mapper
    }

    @Bean
    fun bufferedImageHttpMessageConverter(): BufferedImageHttpMessageConverter? {
        return BufferedImageHttpMessageConverter()
    }
}